package com.kitty.game.task.service.taskHandler;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.activity.model.product.ActivityType;
import com.kitty.game.activity.service.ActivityService;
import com.kitty.game.chat.service.ChatService;
import com.kitty.game.config.NPC;
import com.kitty.game.config.TaskSet;
import com.kitty.game.confirm.model.HelpPeopleConfirm;
import com.kitty.game.equip.message.RespNotifyMiscEx;
import com.kitty.game.npc.model.NpcButton;
import com.kitty.game.role.model.Role;
import com.kitty.game.role.service.RoleService;
import com.kitty.game.task.TaskDataPool;
import com.kitty.game.task.model.product.TaskType;
import com.kitty.game.team.message.RespConfirm;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.team.service.TeamService;
import com.kitty.game.utils.Const;
import com.kitty.listener.event.FightEndEvent;
import com.kitty.mina.message.MessagePusher;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**白邦芒，助人为乐任务处理类*/
@Component
public class HelpPeopleTaskHandler extends TaskHandler {
    /**需要帮助的人数*/
    private static final int NEED_HELP_COUNT = 2;
    /**有这个任务表示助人为乐任务已经完成，可以获得奖励*/
    public static final int HELP_PEOPLE_END_TASKID = 2100;
    /**经验奖励*/
    public static final byte REWARD_TYPE_EXP = 1;
    /**道行奖励*/
    public static final byte REWARD_TYPE_DAOHANG = 2;
    /**潜能奖励*/
    public static final byte REWARD_TYPE_QIANNENG = 3;
    /**领取更多奖励时需要捐助的钱*/
    private static final int REWARD_MORE_DONATE_MONEY = 1500000;
    /**完成时奖励的经验*/
    private final int exp = 50000;
    /**完成时奖励的道行*/
    private final int daohang = 90;
    /**完成时奖励的潜能*/
    private final int qianneng = 5000;
    /**助人为乐最小扫荡等级*/
    private static final int MIN_SAO_DANG_LEVEL = 70;

    private static final String CONTENT_TEMPLATE = "据我所知，目前#Y{0}#n、#Y{1}#n有事需要帮助，你去看看能帮上谁的忙吧。\n" +
            "#R战斗结束时死亡的角色会受到惩罚。#n[帮助{0}][帮助{1}][离开]";
    private static final String HELP_NOT_FOUND = "找不到对应的助人为乐任务！[离开]";

    /**已经接取了任务*/
    private static final String ACCEPTED = "你已经有助人为乐任务在身，快去完成吧。[离开]";
    /**放弃任务后还需要等待CD提示*/
    private static final String WAIT_CD_AFTER_GIVEUP = "你刚才已经乱忙一阵，还是休息休息再来吧。[离开]";
    private static final String REMAIN_COUNT_NOT_ENOUGH = "你今天已经帮了我大忙了，还是先休息休息吧。[离开]";
    private static final String REWARD_MORE = "如果你肯捐助一些钱来救助天墉城里的穷人，我可以给你一些额外的奖励，不知意下如何？[捐助穷人领取额外奖励/" + NpcButton.CHOOSE_REWARD_MORE.getKey() + "][我想领取原有奖励/" + NpcButton.CHOOSE_REWARD_SELF.getKey() + "][我再想想/离开]";
    private static final String REWARD_MORE_CONFIRM_DESC = "你确定要捐助#cBA55DC" + REWARD_MORE_DONATE_MONEY + "#n文钱给天墉城的穷人吗？";
    private static final String MONEY_NOT_ENOUGH = "你的金钱不足！请到积分商城购买";

    /**领取额外奖励时倍数列表，随机获得倍数*/
    private static final List<Integer> REWARD_RATES = Arrays.asList(3, 5, 10);
    /**广播信息的奖励倍数*/
    private static final int BROAD_MSG_REWARD_RATE = 5;
    private static final String BROAD_MSG_TEMPLATE = "#Y{0}#n助人为乐且不计报酬，意外获得了#R{1}倍奖励#n，大家也快去#R天墉城#n找#P白邦芒#P一起帮助别人吧！";
    private static final String DONATE_RATE_MSG_TEMPLATE = "你在助人为乐任务中选择花费#cBA55DC" + REWARD_MORE_DONATE_MONEY + "#n文捐助穷人，意外获得了#R{0}#n倍奖励。";

    private static final String SAO_DANG_NOT_VIP = "只有位列仙班的道友才可快速完成助人为乐任务哦。[我要位列仙班][离开]";
    private static final String SAO_DANG_LEVEL_NOT_ENOUGH = "只有" + MIN_SAO_DANG_LEVEL + "以上的道友才可快速完成助人为乐任务哦。[离开]";
    private static final String SAO_DANG = "天墉城里的百姓有了麻烦事都爱找我帮忙，忙不过来啊，你能来帮帮忙吗？[【助人】我要经验奖励/" + NpcButton.CHOOSE_EXP_REWARD.getKey() + "][【助人】我要道行奖励/" + NpcButton.CHOOSE_DAOHANG_REWARD.getKey() + "][【助人】我要潜能奖励/" + NpcButton.CHOOSE_QIANNENG_REWARD.getKey() + "][离开/离开]";
    private static final String SAO_DANG_RATE_MSG_TEMPLATE = "你在助人为乐任务中选择花费#cBA55DC" + REWARD_MORE_DONATE_MONEY + "#n扫荡，意外获得了#R{0}#n倍奖励。";


    /**开始接取任务*/
    public String startAcceptTask(Role role, NPC npc) {
        /**已经接取时返回已有任务提示*/
        if (getTaskSetByType(role) != null) {
            return ACCEPTED;
        }
        /**放弃任务后的等待时间没到时，返回提示*/
        if (isWaitGiveUpCD(role)) {
            return WAIT_CD_AFTER_GIVEUP;
        }
        /**已经没有剩余次数时返回提示*/
        if (isRemainCountEnough(role) == false) {
            return REMAIN_COUNT_NOT_ENOUGH;
        }

        /**否则返回需要帮助人的选项*/
        return listNeedHelpPeople(role, npc);
    }

    /**是否是放弃任务后的等待时间还没到*/
    private boolean isWaitGiveUpCD(Role role) {
        long giveUpTime = role.getTask().getGiveUpTime(getTaskType());
        if (giveUpTime > 0 && (System.currentTimeMillis()-giveUpTime) < TaskDataPool.DELAY_TIME_AFTER_GIVEUP_HELP_PEOPLE) {
            return true;
        }

        return false;
    }

    /**是否是还有剩余次数*/
    private boolean isRemainCountEnough(Role role) {
        ActivityService activityService = SpringUtils.getBean(ActivityService.class);
        int remainCount = activityService.getRemainCount(role, ActivityType.HELP_PEOPLE_TASK);
        return remainCount > 0;
    }

    /**列出可帮忙的人*/
    public String listNeedHelpPeople(Role role, NPC npc) {
        String[] names = getNeedHelpNames();

        return MessageFormat.format(CONTENT_TEMPLATE, (Object[])names);
    }

    /**获得需要被帮助的人的名称*/
    public String[] getNeedHelpNames() {
        String[] needHelpNames = new String[NEED_HELP_COUNT];

        List<String> names = new ArrayList<>(TaskDataPool.helpTaskByName.keySet());
        for (int i=0; i<NEED_HELP_COUNT; i++) {
            int index = ThreadLocalRandom.current().nextInt(names.size());
            String name = names.remove(index);

            needHelpNames[i] = name;
        }

        return needHelpNames;
    }

    @Override
    public TaskType getTaskType() {
        return TaskType.HELP_PEOPLE;
    }

    /**通过传入的名字接取对应的助人为乐任务*/
    public String acceptTaskByNpcName(Role role, String npcName) {
        TaskSet taskSet = taskService.getHelpTaskByNpcName(role, npcName);
        if (taskSet == null) {
            /**客户端改了数据？？*/
            return HELP_NOT_FOUND;
        }
        /**已经没有剩余次数时返回提示*/
        if (isRemainCountEnough(role) == false) {
            return REMAIN_COUNT_NOT_ENOUGH;
        }

        acceptTask(role, taskSet);

        return null;
    }

    @Override
    public void doAfterSubmit(Role role, TaskSet taskSet) {
        super.doAfterSubmit(role, taskSet);

        /**没有下一任务时，表明整组任务已经完成，此时接取领取奖励任务*/
        if (getNextTask(role, taskSet) == null) {
            TaskSet rewardTaskSet = taskService.getTaskSet(HELP_PEOPLE_END_TASKID, role);
            acceptTask(role, rewardTaskSet);
        }

        /**提交后则重置掉*/
        doResetTask(role, taskSet);
    }

    /**选择助人为乐的奖励*/
    public String chooseReward(Role role, byte rewardType) {
        /**如果没有接取领奖任务却选择奖励，则进行扫荡*/
        if (role.getTask().isAccepted(HELP_PEOPLE_END_TASKID) == false) {
            return doSaoDang(role, rewardType);
        }

        /**记录下选择奖励类型*/
        role.getTalk().pushChooseParam(Const.HELP_PEOPLE_REWARD_TYPE_KEY, rewardType);

        return REWARD_MORE;
    }

    /**选择领取额外奖励*/
    public void chooseRewardMore(Role role ,NPC npc) {
        role.setConfirm(new HelpPeopleConfirm());

        /**弹出确认框*/
        RespConfirm respConfirm = new RespConfirm();
        respConfirm.setTips(REWARD_MORE_CONFIRM_DESC);
        MessagePusher.pushMessage(role, respConfirm);
    }

    /**确认领取额外奖励*/
    public void confirmRewardMore(Role role) {
        if (canGiveReward(role) == false) {
            return ;
        }

        /**判断玩家是否有足够的金钱*/
        if (role.getMoney() < REWARD_MORE_DONATE_MONEY) {
            MessagePusher.pushMessage(role, new RespMsg(MONEY_NOT_ENOUGH));
            return;
        }
        /**扣除对应的金钱*/
        SpringUtils.getRoleService().subtractMoney(role, REWARD_MORE_DONATE_MONEY);

        giveRateReward(role, false);
    }

    /**能否给奖励*/
    private boolean canGiveReward(Role role) {
        /**没有完成任务时，返回false*/
        if (!role.getTask().isAccepted(HELP_PEOPLE_END_TASKID)) {
            return false;
        }

        /**没有剩余次数时，返回false*/
        if (isRemainCountEnough(role) == false) {
            return false;
        }

        return true;
    }

    /**给随机位数奖励*/
    private void giveRateReward(Role role, boolean isSaoDang) {
        /**根据对应的倍数给奖励*/
        int rewardRate = getRewardRate(role);
        giveReward(role, rewardRate);

        if (rewardRate >= BROAD_MSG_REWARD_RATE) {
            /**倍数达到指定值时，发送谣言信息*/
            String msg = MessageFormat.format(BROAD_MSG_TEMPLATE, role.getName(), rewardRate);
            SpringUtils.getBean(ChatService.class).sendNumor(msg, Const.BRODCAST_MSG_TYPE_ROLE);
        }

        /**发送获得倍数信息*/
        String template = isSaoDang ? SAO_DANG_RATE_MSG_TEMPLATE : DONATE_RATE_MSG_TEMPLATE;
        String msg = MessageFormat.format(template, rewardRate);
        MessagePusher.pushMessage(role, new RespNotifyMiscEx(msg));
    }

    /**获得奖励倍数*/
    private int getRewardRate(Role role) {
        int index = ThreadLocalRandom.current().nextInt(REWARD_RATES.size());
        return REWARD_RATES.get(index);
    }

    /**领取原有奖励*/
    public void chooseRewardSelf(Role role, NPC npc) {
        if (canGiveReward(role) == false) {
            return ;
        }

        /**原有奖励，倍数传1*/
        giveReward(role, 1);
    }

    /**给奖励*/
    private void giveReward(Role role, int rewardRate) {
        /**增加次数*/
        SpringUtils.getBean(ActivityService.class).addFinishCount(role, ActivityType.HELP_PEOPLE_TASK, 1);

        doGiveReward(role, rewardRate);

        /**给奖励后重置掉领奖任务*/
        TaskSet taskSet = getTaskSetByType(role);
        if (taskSet != null) {
            doResetTask(role, taskSet);
            doAfterReset(role, taskSet);
        }
    }

    /**给奖励*/
    private void doGiveReward(Role role, int rewardRate) {
        byte rewardType = (Byte)role.getTalk().popChooseParam(Const.HELP_PEOPLE_REWARD_TYPE_KEY);

        RoleService roleService = SpringUtils.getRoleService();
        switch (rewardType) {
            case REWARD_TYPE_EXP:
                int addExp = role.getLevel() * exp * rewardRate;
                roleService.addExp(role, addExp, role.getLevel(),role.getPetBox().getFightPetId());
                break;
            case REWARD_TYPE_DAOHANG:
                int daohang = role.getLevel() * this.daohang * rewardRate;
                roleService.addTao(role, daohang);
                break;
            case REWARD_TYPE_QIANNENG:
                int addQianneng = role.getLevel() * this.qianneng * rewardRate;
                roleService.addPot(role, addQianneng);
                break;
        }
    }

    /**助人为乐任务不每日重置任务，只重置次数*/
    @Override
    public boolean canResetTask(Role role, TaskSet taskSet) {
        return false;
    }

    /**放弃任务*/
    public void giveUpTask(Role role) {
        TaskSet taskSet = getTaskSetByType(role);
        if (taskSet == null) {
            /**找不到任务时，返回*/
            return ;
        }

        /**放弃*/
        giveUpTask(role, taskSet);
    }

    @Override
    public boolean canGiveUpTask(Role role, TaskSet taskSet) {
        return true;
    }

    @Override
    public void doAfterGiveUp(Role role, TaskSet taskSet) {
        role.getTask().addGiveUpTime(getTaskType(), System.currentTimeMillis());

        super.doAfterGiveUp(role, taskSet);
    }

    /**选择扫荡*/
    public String chooseSaoDao(Role role, NPC npc) {
        String check = checkSaoDang(role);
        if (check != null) {
            return check;
        }

        return SAO_DANG;
    }

    /**进行扫荡*/
    private String doSaoDang(Role role, byte rewardType) {
        String check = checkSaoDang(role);
        if (check != null) {
            return check;
        }

        /**判断玩家是否有足够的金钱*/
        if (role.getMoney() < REWARD_MORE_DONATE_MONEY) {
            MessagePusher.pushMessage(role, new RespMsg(MONEY_NOT_ENOUGH));
            return null;

        }
        /**扣除对应的金钱*/
        SpringUtils.getRoleService().subtractMoney(role, REWARD_MORE_DONATE_MONEY);

        role.getTalk().pushChooseParam(Const.HELP_PEOPLE_REWARD_TYPE_KEY, rewardType);
        giveRateReward(role, true);

        return null;
    }

    /**能否扫荡*/
    private String checkSaoDang(Role role) {
        /**没有剩余次数时，返回*/
        if (isRemainCountEnough(role) == false) {
            return REMAIN_COUNT_NOT_ENOUGH;
        }
        /**不是vip时，返回*/
        if (role.isVip() == false) {
            return SAO_DANG_NOT_VIP;
        }
        /**等级不足时，返回*/
        if (role.getLevel() < MIN_SAO_DANG_LEVEL) {
            return SAO_DANG_LEVEL_NOT_ENOUGH;
        }

        return null;
    }

    @Override
    public void doFightFail(Role role, FightEndEvent fightEndEvent) {
        super.doFightFail(role, fightEndEvent);

        TeamService teamService = SpringUtils.getTeamService();
        teamService.memberHandleThreadLocal(role, memberRole -> SpringUtils.getRoleService().punishFightDead(memberRole));
    }

    /**选择领取助人为乐任务*/
    public void chooseHelpPeopleTask(Role role, NPC npc) {
        String content = startAcceptTask(role, npc);
        if (content != null) {
            SpringUtils.getNpcService().sendNpcContent(role, npc, content);
        }
    }

    /**选择帮助谁，领取对应的任务*/
    public void chooseHelpWho(Role role, NPC npc, String msg) {
        String name = msg.replace(NpcButton.CHOOSE_HELP_WHO_PREFIX.getKey(), "");
        String content = acceptTaskByNpcName(role, name);
        if (content != null) {
            SpringUtils.getNpcService().sendNpcContent(role, npc, content);
        }
    }

    /**选择助人为乐的奖励*/
    public void chooseHelpReward(Role role, NPC npc, byte rewardType) {
        String content = chooseReward(role, rewardType);
        if (content != null) {
            SpringUtils.getNpcService().sendNpcContent(role, npc, content);
        }
    }

    /**选择助人为乐的扫荡*/
    public void chooseSaoDang(Role role, NPC npc) {
        String content = chooseSaoDao(role, npc);
        if (content != null) {
            SpringUtils.getNpcService().sendNpcContent(role, npc, content);
        }
    }
}
